package com.niit.scala

import scala.io.StdIn

/*
总结：
 1.三引号表达式用来保存大量文本，同时可以保留换行、空格等格式
 2.惰性赋值，当有些自定义的常量数据较大的时候，而这些数据并不是马上去加载到JVM内存中，可以使用惰性赋值提高效率
 3.标识符就是给变量、方法、类起名字，Scala和Java中的标识符非常相似
    命令规则：
      必须是由大小英文字母、数字、下划线_、美元符号$四部分组成
      数字不能开头
      不能和Scala关键字重名
      最好做到见名知意
    命令规范：
      变量、方法：小驼峰命名，从第二个单词开始每个单词的首字母大写
      类、特质：大驼峰命名，每个单词的首字母都大写
      包：全部小写，一般是公司域名反写
 4.数据类型：
    所有类型都以大写字母开头
    整型使用Int，而不是Integer
    定义变量可以不写类型，让编译器自动推断
    默认整型Int,默认浮点类型是Double
    Any是所有类型的父类    相当于Java中Object
   Scala的类型关系
      AnyVal所有数值类型父类   AnyRef所有引用类型的父类
      Unit类似于Java中void,一般作为返回值
      Null是所有引用类型的子类，只有一个实例null
      Nothing是所有类型的子类，不能创建该类型的实例，一般结合异常使用
 5.类型转换
      自动类型转换： 大数据类型  转 小数据类型
      强制类型转换：  小数据类型  转  大数据类型  缺点：可能会损失精度
      值类型和字符串类型的转换
          1.字符串的拼接
          2.值.toString
          3.字符串.toXxx (Xxx：要转换的数据类型)

 */
object Base_02 {

  def main(args: Array[String]): Unit = {

    //1.三引号 """：保存的字符串信息同样保留格式
    val str1 = "盼望着，盼望着，东风来了，春天的脚步近了。" +
      "一切都像刚睡醒的样子，欣欣然张开了眼。山朗润起来了，水涨起来了，太阳的脸红起来了。" +
      "小草偷偷地从土里钻出来，嫩嫩的，绿绿的。园子里，田野里，瞧去，一大片一大片满是的。" +
      "坐着，躺着，打两个滚，踢几脚球，赛几趟跑，捉几回迷藏。风轻悄悄的，草软绵绵的。"
    val str2 =
      """
        |盼望着，盼望着，东风来了，春天的脚步近了。
        |
        |一切都像刚睡醒的样子，欣欣然张开了眼。山朗润起来了，水涨起来了，太阳的脸红起来了。
        |
        |小草偷偷地从土里钻出来，嫩嫩的，绿绿的。园子里，田野里，瞧去，一大片一大片满是的。坐着，躺着，打两个滚，踢几脚球，赛几趟跑，捉几回迷藏。风轻悄悄的，草软绵绵的。
        |""".stripMargin

    println( str1)
    println("---------------------------------")
    println(str2)

    //2.惰性赋值。当使用惰性赋值的时候，该变量在用到的时候才会加载到内存当中.格式： lazy val 变量名 = 数值
    lazy val name = "张三"
    println(name)

    //3.数值转换
    //3.1 自动数据类型转换 ： 用大的数据类型装小的数据类型
    //从小到大的数据类型依次为：Byte -- Short -- Int -- Long -- Float -- Double
    var a:Int = 10
    var b:Long = a
    var c:Double = a + 3.14
    println(a,b,c)
    //3.2 强制数据类型转换： 用小的数据类型装大的数据类型 缺点：可能会损失精度
    // val/var 变量名:数据类型 = 数值.toXxx (Xxx:要转换的数据类型)
    val d:Double = 3.81
    val e:Int = d.toInt
    println(e)
    //3.3数值转换为字符串类型
    // 任意类型对字符串进行拼接，最终类型为字符串
    val f:String  =3.14 + ""
    val g:String = 3.14.toString
    //3.4字符串类型转换数值类型
    val h:String = "100"
    val i:Int= h.toInt
    val j:Float = h.toFloat
    println(i,j)
    //问题：布尔类型能不能数值类型 true:1 false:0
    //val k:Int = true.toInt
    val l:String = true.toString

    //4.键盘录入
    //字符串键盘录入 StdIn.readLine()
    //println("请输入一个字符串："+StdIn.readLine())
    /*
    println("请输入你们最大愿望：")
    val str  = StdIn.readLine()
    println("我的最大的愿望："+str)

     */

    //5.余数
    var q = 27 % 5 //背后运算逻辑：  27 - 27/5 *5 == 27 - 5 *5 =27 - 25 = 2
    println(q)
//    var p = 10
//    var n += p // n = n + p
    var w = "abd".eq("rfg")
    println(w)

    //6.逻辑运算符
    println(1>2 && 2>1)//false  && 两者都成立才成立，有一方成立也不成立
    println( 1>2 || 2 > 1)//true 两者有一个成立就成立，两者都不成立就不成立

    println(!(1>2) && 2>1 )//true
    var cc =1
    //7.if - else if  - else
    val score = 80
    if(score >=90 && score <=100){
      println("你很优秀了")
    }else if(score>=80 && score<90){
      println("一般般")
    }else if (score>=0 && score< 80 ){
      println("努力吧")
    }else{
      println("成绩无效")
    }
    //8.三目(元)运算符  int a = 2>1?1:0
    //Scala中没有三目运算符 ，可以用if else来代替
    //int a = 2>1?1:0
    var ii = if(2>1) 1 else 0

    //9.块表达式 { 代码 }  --->代码块
    val kuai = {
      10+100
      1+1
      3+3//最后的值才是块表达式的返回值
      if(2>1){
        println("成立")
      }
      //没有任何东西返回值
    }
    println(kuai)// 结果还是6吗？ 不是6，是一个空(),元组   成立会不会输出？ 会

    //10.for循环   for(i <- 表达式/集合)
    //需求：输出10次Hello Scala
    for (i <- 1 to 10){//[1,10]

      println("Hello Scala"+i)
    }

    //11.for循环的守卫. 在for表达式可以添加if判断语句，这个if判断就被称之为守卫
    //需求：写一个 1-10之间输出可以被二整除的数字
    for (i <- 1 to 10 if i % 2 ==0){
      println(i)
    }

    //12.for循环推导式 。for循环也可以有返回值了，可以使用yield对for循环的数据进行返回，返回的记过是一个集合
    //返回一个 1-10 10的倍数
    val v =  for(i <- 1 to 10) yield i *10
    println(v)

    //13.while  do-while
    //输出 1-10
    var count = 1
    while (count <=10){
      println(count)
      count += 1
    }
    do {
      println(count)
      count -=1
    }while(count>=1)

    //break 和 continue 。Scala是没有continue关键字
    //Scala想用break需要在for循环外面套一层breakable
    import scala.util.control.Breaks.{break,breakable}
    breakable{
      for (i <- 1 to 10){
        if(i==5){
          break
        }else{
          println(i)
        }
      }
    }

    //需求，输出 1-10.跳5
    // breakablea放在for循环的外面就是break的作用，放在for循环的里面就是continue的作用
    for (i <- 1 to 10){
      breakable{
        if(i==5){
          break
        }else{
          println(i)
        }
      }
    }

    //15.方法
    /*
      def 方法名(参数名:参数类型,参数名:参数类型):[return type]={
        方法体
      }
      注意：
          1.参数列表列表的参数类型是不能省略
          2.返回值类型可以省略，由Scala编译器进行推断
          3.返回值可以不写return,默认就是块表达式的值
     */
    //代码执行顺序： 从上到下 从左到右 从括号里到括号外
      var res = getMax1(20,10) //20
      println(res)
      println( getMax1(20,10) )//20
      println(getMax2(60,40))
      println(getMax3())
     //带名参数：在传入实参的时候指定给形参传递数据
    getMax1(b=20,a=10)
  }

  //方式一：标准写法
  def getMax1(a:Int,b:Int): Int ={
       if(a>b) a else b
  }
  //方式二：优化写法
  def getMax2(a:Int,b:Int)= if(a>b) a else b

  //默认参数：直接在形参上定义真实数据。如果没有实参的传入，那么a,b久默认为6，7
  def getMax3(a:Int=6,b:Int=7): Int ={
    if(a>b) a else b
  }
}
